package compilador;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Scanner;

import compilador.gerador.GeradorDeCodigo;
import compilador.semantico.SemanticException;
import compilador.semantico.XMIParser;

/**
 * 
 */
public class Runner {

	private boolean hasError = false;

	public boolean hasError() {
		return this.hasError;
	}

	private void compile(String file) {
		Scanner in = null;
		this.hasError = false;
		try {
			System.out.println("Processando arquivo " + file);
			in = new Scanner(new FileInputStream(file));
			while (in.hasNextLine()) {
				processLine(in.nextLine());
			}
		} catch (FileNotFoundException e) {
			erroGenerico("Arquivo " + file + " nao existe!");
		} finally {
			if (in != null)
				in.close();
		}
	}

	private void processLine(String line) {
		String[] cmdLine = line.split("::");

		String cmdName = cmdLine[0];

		String[] lineCol = cmdLine[1].split(",");
		int lin = Integer.parseInt(lineCol[0]);
		int col = Integer.parseInt(lineCol[1]);

		String[] cmdArgs = new String[0];
		if (cmdLine.length > 2) {
			cmdArgs = cmdLine[2].split(" ");
		}

		try {
			Command cmd = CommandBuilder.createCommand(cmdName);
			cmd.run(cmdArgs);
		} catch (SemanticException e) {
			erroSemantico(e.getMessage(), lin, col);
		} catch (Exception e) {
			erroGenerico(e.getMessage());
			e.printStackTrace();
		}
	}

	private void erroGenerico(String message) {
		this.hasError = true;
		System.out.println("Erro Nao Identificado:");
		System.err.println("\t" + message);
	}

	private void erroSemantico(String message, int linha, int coluna) {
		this.hasError = true;
		System.out.println("Erro Semantico:");
		System.err.println("\tLinha " + linha + ", Coluna " + coluna);
		System.err.println("\t" + message);
	}

	// Main
	public static void main(String[] args) throws IOException {
		if (args.length != 2) {
			System.err.println("Parametros invalidos, voce deve passar o arquivo xmi e os arquivo processado pelo analisador lexico/sintatico.");
			System.exit(-1);
		}

		// primeiro parametro eh o arquivo XMI a ser processado
		new XMIParser().parse(args[0]);
		// gerar codigo para as classes lidas do xmi
		GeradorDeCodigo gerador = GeradorDeCodigo.getInstance();
		gerador.createClassesStub();

		// do segundo parametro em diante trata-se dos arquivos de saída do
		// analisador lexico/sintatico
		// devem ser compilados pelo nosso programa
		// o Runner ira ler o arquivo e executar os comandos especificados
		// os commandos podem ser acoes semanticas ou acoes de geracao de codigo
		Runner runner = new Runner();
		runner.compile(args[1]);

		if (!runner.hasError)
			gerador.writeClasses();
	}
}